import { handleActions, Action } from 'redux-actions';
import produce from 'immer';
import { EventEmitter } from 'ahooks/lib/useEventEmitter';

import { isValidKey } from '../../util/object';
import { actionTypes } from './actions';
import {
  isUserBasicStringInfo,
  isUserBasicNumberInfo,
} from './components/basic-info/constants';

const initState: QA.ReduxState = {
  next$: undefined,
  pageLoading: true,
  open: false,
  mergeUuid: '',
  userUuid: '',
  userNameVisible: false,
  userNumVisible: false,
  jobPositionVisible: false,
  affiliatedVisible: false,
  workUnitVisible: false,
  operatingPostVisible: false,
  questionnaireUuid: '',
  subTitle: '',
  title: '',
  description: '',
  epilog: '',
  logo: '',
  userAnswerProgressState: 0,
  operatingPost: [],
  jobPosition: [],
  affiliatedUnit: [],
  workUnit: [],
  questionList: [],
  scoreList: [],
  userInitBasic: {
    name: undefined,
    num: undefined,
    email: undefined,
    gender: undefined,
    maritalStatus: undefined,
    childrenSituation: undefined,
    age: undefined,
    education: undefined,
    workUnit: undefined,
    affiliated: undefined,
    jobPosition: undefined,
    operatingPost: undefined,
  },
};

export default handleActions<QA.ReduxState, any>(
  {
    [actionTypes.INIT_QUESTIONNAIRE]:
      (state, { payload }: Action<QA.QuestionnaireInitBaisc>) => produce(state,
        (draftState) => {
          const props = Object.keys(
            draftState
          );

          props.forEach((
            prop
          ) => {
            if (isValidKey(prop, payload) && isValidKey(prop, draftState)) {
              draftState[prop] = payload[prop];
            }
          });
        }),
    [actionTypes.CLEAR_USER]:
      (state) => produce(state,
        (draftState) => {
          draftState.userInitBasic = {
            name: undefined,
            num: undefined,
            email: undefined,
            gender: undefined,
            maritalStatus: undefined,
            childrenSituation: undefined,
            age: undefined,
            education: undefined,
            workUnit: undefined,
            affiliated: undefined,
            jobPosition: undefined,
            operatingPost: undefined,
          };
        }),
    [actionTypes.INIT_USER_UUID]:
      (state, { payload }: Action<string>) => produce(state,
        (draftState) => {
          draftState.userUuid = payload;
        }),
    [actionTypes.INIT_MERGE_UUID]:
      (state, { payload }: Action<string | undefined>) => produce(state,
        (draftState) => {
          draftState.mergeUuid = payload;
        }),
    [actionTypes.START_PAGE_LOADING]:
      (state) => produce(state,
        (draftState) => {
          draftState.pageLoading = true;
        }),
    [actionTypes.STOP_PAGE_LOADING]:
      (state) => produce(state,
        (draftState) => {
          draftState.pageLoading = false;
        }),
    [actionTypes.UPDATE_SCORE]:
      (state, { payload }: Action<{
        index: number, score?: number
      }>) => produce(state,
        (draftState) => {
          const currentIndex = payload.index;
          draftState.scoreList[currentIndex] = payload.score;
        }),
    [actionTypes.INIT_SCORE_LIST]:
      (state, { payload }: Action<{
        questionId: number, score?: number
      }[]>) => produce(state,
        (draftState) => {
          draftState.scoreList = payload?.map((item) => item.score);
        }),
    [actionTypes.INIT_NEXT_EVENT]:
      (state, { payload }: Action<
        EventEmitter<void> | undefined
      >) => produce(state,
        (draftState) => {
          draftState.next$ = payload;
        }),
    [actionTypes.UPDATE_USER_PROP]:
      (state, { payload }: Action<{
        key: keyof QA.UserInitBasic, value: string | number
      }>) => produce(state,
        (draftState) => {
          const { key, value } = payload;

          if (
            typeof value === 'string'
            && isUserBasicStringInfo(key)
          ) {
            draftState.userInitBasic[key] = value;
          }

          if (
            typeof value === 'number'
            && isUserBasicNumberInfo(key)
          ) {
            draftState.userInitBasic[key] = value;
          }
        }),
  },
  initState
);
